/*
 * Unidata Platform
 * Copyright (c) 2013-2020, UNIDATA LLC, All rights reserved.
 *
 * Commercial License
 * This version of Unidata Platform is licensed commercially and is the appropriate option for the vast majority of use cases.
 *
 * Please see the Unidata Licensing page at: https://unidata-platform.com/license/
 * For clarification or additional options, please contact: info@unidata-platform.com
 * -------
 * Disclaimer:
 * -------
 * THIS SOFTWARE IS DISTRIBUTED "AS-IS" WITHOUT ANY WARRANTIES, CONDITIONS AND
 * REPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE
 * IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,
 * FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE AND
 * THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.
 */
package org.unidata.mdm.rest.data.configuration;

import java.util.Arrays;
import java.util.Collections;
import javax.ws.rs.core.Application;
import javax.ws.rs.ext.RuntimeDelegate;

import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import org.apache.cxf.Bus;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.openapi.OpenApiFeature;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.unidata.mdm.rest.data.service.DataEntityRestService;
import org.unidata.mdm.rest.data.service.DataMergeRestService;
import org.unidata.mdm.rest.data.service.DataRelationsRestService;
import org.unidata.mdm.rest.data.service.DataRestApplication;
import org.unidata.mdm.rest.data.service.FavoriteEtalonsRestService;
import org.unidata.mdm.rest.data.service.RestoreRestService;
import org.unidata.mdm.rest.system.exception.RestExceptionMapper;
import org.unidata.mdm.rest.system.service.ReceiveInInterceptor;
import org.unidata.mdm.rest.system.util.OpenApiMetadataFactory;

/**
 * @author Alexander Malyshev
 */
@Configuration
public class DataRestConfiguration {

    @Bean
    public Application dataRestApplication() {
        return new DataRestApplication();
    }

    @Bean
    public DataEntityRestService dataEntityRestService() {
        return new DataEntityRestService();
    }

    @Bean
    public DataRelationsRestService dataRelationsRestService() {
        return new DataRelationsRestService();
    }

    @Bean
    public DataMergeRestService dataMergeRestService() {
        return new DataMergeRestService();
    }

    @Bean
    public RestoreRestService restoreRestService() {
        return new RestoreRestService();
    }

    @Bean
    public FavoriteEtalonsRestService favoriteEtalonsRestService() {
        return new FavoriteEtalonsRestService();
    }

    @Bean
    public Server server(
            final Bus cxf,
            final Application dataRestApplication,
            final JacksonJaxbJsonProvider jacksonJaxbJsonProvider,
            final RestExceptionMapper restExceptionMapper,
            final ReceiveInInterceptor receiveInInterceptor,
            final DataEntityRestService dataEntityRestService,
            final DataRelationsRestService dataRelationsRestService,
            final DataMergeRestService dataMergeRestService,
            final RestoreRestService restoreRestService,
            final FavoriteEtalonsRestService favoriteEtalonsRestService) {

        JAXRSServerFactoryBean jaxrsServerFactoryBean = RuntimeDelegate.getInstance()
                .createEndpoint(dataRestApplication, JAXRSServerFactoryBean.class);

        final OpenApiFeature dataOpenApiFeature = OpenApiMetadataFactory.openApiFeature(
                "Unidata data API",
                "Unidata data REST API operations",
                dataRestApplication, cxf,
                "org.unidata.mdm.rest.data.service");

        jaxrsServerFactoryBean.setFeatures(Arrays.asList(dataOpenApiFeature));
        jaxrsServerFactoryBean.setProviders(Arrays.asList(jacksonJaxbJsonProvider, restExceptionMapper));
        jaxrsServerFactoryBean.setInInterceptors(Collections.singletonList(receiveInInterceptor));
        jaxrsServerFactoryBean.setServiceBeans(Arrays.asList(
                dataEntityRestService,
                dataRelationsRestService,
                dataMergeRestService,
                restoreRestService,
                favoriteEtalonsRestService));

        return jaxrsServerFactoryBean.create();
    }
}
